package travianBot.botScripts;

import java.io.IOException;
import java.util.HashMap;

import org.apache.log4j.Logger;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;

import travianBot.LinkMaker;
import travianBot.ResourceEntry;
import travianBot.ResourceManager;
import travianBot.TraderDetails;
import travianBot.TravianBot;
import travianBot.TravianBotException;
import travianBot.TravianBotUtil;
import travianBot.Village;

public class DonateResourceScript extends TravianScript {
	
	int 	villageResourceMin = 0;
	String 	collecorVillage;
	int		traderCount=0;
	
	static Logger log=Logger.getLogger(DonateResourceScript.class);
	
	public DonateResourceScript(String csvLine){
		init(csvLine);
	}
	
	public void init(String csvLine){
		String[] tokens = csvLine.split(",");
		
		int cursorToken 		= Integer.parseInt(tokens[0]);
		String villageNameToken = tokens[1];
		String typeToken 		= tokens[2];
		String collectingVillage= tokens[3];
		String villageResourceMin=tokens[4];
		String traderCount		=tokens[5];
		
		this.cursorPosition = cursorToken;
		this.villageName = villageNameToken;
		this.type = typeToken;
		this.collecorVillage = collectingVillage;
		this.villageResourceMin = Integer.parseInt(villageResourceMin.trim());
		this.traderCount = Integer.parseInt(traderCount.trim());
	}
	
	@Override
	public void runScript(TravianBot travianBot, HashMap<String,String> sessionInfoMap) throws TravianBotException {
		donateResources(travianBot, this.villageName, this.collecorVillage, this.villageResourceMin, this.traderCount);
	}
	
	public boolean donateResources(TravianBot travianBot, String donorVillageName, String collectorVillageName, int villageResourceMin, int traderCount) throws TravianBotException{
		// fetch the details of the receiving village
		Village collectorVillage = travianBot.loadVillage(collectorVillageName);
		if(collectorVillage == null){
			throw new TravianBotException("Village:"+collectorVillageName+" does not exist");
		}
		
		Village donorVillage = travianBot.loadVillage(donorVillageName);
		if(donorVillage == null){
			throw new TravianBotException("Village:"+donorVillageName+" does not exist");
		}
		
		// load the buildings page
		String buildingsPage = travianBot.getHttpContents(LinkMaker.BUILDINGS_PAGE);
		donorVillage.initialiseBuildings(buildingsPage);
		ResourceEntry donorBuilding = donorVillage.getBuildingResourceEntry(Village.MARKETPLACE);
		
		// get the link for the market
		String donorMarketLink = LinkMaker.getBuildingPageLink(donorBuilding);
		// load the market
		String htmlContent = travianBot.getHttpContents(donorMarketLink);
		//log.debug(htmlContent);
		// collect the values needed
		TraderDetails traderDetails = ResourceManager.collectTraderDetails(htmlContent);
		
		// work out what we plan to send
		HashMap<String,Integer> tradingValuesMap = null;
		
		try{
			tradingValuesMap = ResourceManager.calculateMarketSupplyValues(donorVillage.getResourceCounters(), 
	    		collectorVillage.getResourceCounters().values(), 
	    		traderDetails, traderCount, villageResourceMin);
		}catch(TravianBotException tbe){
			log.info("Sending from "+donorVillageName+" failed:"+tbe.getMessage());
		}
		//
		// get the url values
		//
		HashMap<String,String> urlQueryMap = new HashMap<String,String>();
		
		Integer resource=0; 
		String  displayString="";
		
		if(tradingValuesMap != null){
			resource = tradingValuesMap.get(Village.WOODCUTTER);
			if(resource != null){
				urlQueryMap.put("r1", ""+resource);
				//urlQueryMap.put("r1", ""+500);
			}
			displayString+="wd:"+resource;
			resource = tradingValuesMap.get(Village.CLAY_PIT);
			if(resource != null){
				urlQueryMap.put("r2", ""+resource);
			}
			displayString+=",cl:"+resource;
			resource = tradingValuesMap.get(Village.IRON_MINE);
			if(resource != null){
				urlQueryMap.put("r3", ""+resource);
			}
			displayString+=",ir:"+resource;
			resource = tradingValuesMap.get(Village.WHEAT_FIELD);
			if(resource != null){
				urlQueryMap.put("r4", ""+resource);
			}
			displayString+=",wh:"+resource;
			String dname=collectorVillageName;
			
			ResourceEntry buildingDetails = donorVillage.getBuildingResourceEntry(Village.MARKETPLACE);
						
			urlQueryMap.put("x", "");
			urlQueryMap.put("y", "");
			urlQueryMap.put("s1.x", "");
			urlQueryMap.put("s1.y", "");
			urlQueryMap.put("s1", "ok");
			urlQueryMap.put("dname", collectorVillageName);
			urlQueryMap.put("id", buildingDetails.location);
			//create URL and submit it.
			//String verifyTradeLink = LinkMaker.getBuildingPageLink(buildingDetails);
			String buildLink = LinkMaker.getBuildLink();
			//System.out.println(verifyTradeLink);
			
			// post details to travian
			String verifyTradeHtml = TravianBotUtil.getHttpPostContents(travianBot.getHttpclient(), urlQueryMap, buildLink);			
			//System.out.println(verifyTradeHtml);
			
			DonateResourceHiddenValues hiddenValues = getHiddenValues(verifyTradeHtml);
			
			// create second url and submit it
			urlQueryMap.remove("dname");
			urlQueryMap.put("a", hiddenValues.a);
			urlQueryMap.put("sz", hiddenValues.sz);
			urlQueryMap.put("kid", hiddenValues.kid);
			
			// post details to travian
			String completedTradeHtml = TravianBotUtil.getHttpPostContents(travianBot.getHttpclient(), urlQueryMap, buildLink);			
			
			log.info("Sending"+ "["+displayString+"]" +"from: "+donorVillageName+" to "+collectorVillageName);
		}
		
		return true;
	}
	
	public static DonateResourceHiddenValues getHiddenValues(String htmlContent ) throws TravianBotException{
		// 
		// parse the returned page for details
		//
		DonateResourceHiddenValues hiddenValues = new DonateResourceHiddenValues();
		HtmlCleaner htmlCleaner = new HtmlCleaner();
		try {
			TagNode node = htmlCleaner.clean(htmlContent);
			Object[] nodeArray = node.evaluateXPath("//form[@name='snd']");
			
			if(nodeArray != null && nodeArray.length > 0){
				TagNode formNode = (TagNode)nodeArray[0];
				
				nodeArray = formNode.evaluateXPath("//input[@name='a']");
				if(nodeArray != null && nodeArray.length > 0){
					TagNode inputNode = (TagNode)nodeArray[0];
					hiddenValues.a = inputNode.getAttributeByName("value");
				}
				nodeArray = formNode.evaluateXPath("//input[@name='sz']");
				if(nodeArray != null && nodeArray.length > 0){
					TagNode inputNode = (TagNode)nodeArray[0];
					hiddenValues.sz = inputNode.getAttributeByName("value");
				}
				nodeArray = formNode.evaluateXPath("//input[@name='kid']");
				if(nodeArray != null && nodeArray.length > 0){
					TagNode inputNode = (TagNode)nodeArray[0];
					hiddenValues.kid = inputNode.getAttributeByName("value");
				}				
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new TravianBotException("problems getting hidden values from marked send page", e);
		} catch (XPatherException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new TravianBotException("xpath problems getting hidden values from marked send page", e);
		}
		
		return hiddenValues;
	}

}
